<?php
declare(strict_types=1);

namespace SixShop\Message\Model;

use SixShop\Message\Entity\PrivateMessageEntity;
use SixShop\Message\Entity\MessageSettingEntity;
use think\facade\Db;

/**
 * 私信模型
 */
class PrivateMessageModel
{
    /**
     * 获取私信列表
     *
     * @param array $params 查询参数
     * @param int $page 页码
     * @param int $limit 每页数量
     * @return array
     */
    public function getList(array $params = [], int $page = 1, int $limit = 10)
    {
        $query = PrivateMessageEntity::where('1=1');
        
        // 发送者ID筛选
        if (!empty($params['from_user_id'])) {
            $query->where('from_user_id', $params['from_user_id']);
        }
        
        // 接收者ID筛选
        if (!empty($params['to_user_id'])) {
            $query->where('to_user_id', $params['to_user_id']);
        }
        
        // 是否已读筛选
        if (isset($params['is_read']) && $params['is_read'] !== '') {
            $query->where('is_read', $params['is_read']);
        }
        
        // 内容搜索
        if (!empty($params['content'])) {
            $query->where('content', 'like', '%' . $params['content'] . '%');
        }
        
        // 时间范围筛选
        if (!empty($params['start_time'])) {
            $query->where('create_time', '>=', strtotime($params['start_time']));
        }
        if (!empty($params['end_time'])) {
            $query->where('create_time', '<=', strtotime($params['end_time']));
        }
        
        // 获取总数
        $total = $query->count();
        
        // 获取分页数据
        $list = $query->order('id', 'desc')
            ->page($page, $limit)
            ->select()
            ->toArray();
        
        return [
            'list' => $list,
            'total' => $total,
            'page' => $page,
            'limit' => $limit,
        ];
    }
    
    /**
     * 获取用户私信列表
     *
     * @param int $userId 用户ID
     * @param array $params 查询参数
     * @param int $page 页码
     * @param int $limit 每页数量
     * @return array
     */
    public function getUserMessages(int $userId, array $params = [], int $page = 1, int $limit = 10)
    {
        $query = PrivateMessageEntity::where(function ($query) use ($userId) {
            $query->where('to_user_id', $userId)
                ->whereOr('from_user_id', $userId);
        });
        
        // 对话用户ID筛选
        if (!empty($params['partner_id'])) {
            $partnerId = $params['partner_id'];
            $query->where(function ($query) use ($userId, $partnerId) {
                $query->where(function ($query) use ($userId, $partnerId) {
                    $query->where('from_user_id', $userId)
                        ->where('to_user_id', $partnerId);
                })->whereOr(function ($query) use ($userId, $partnerId) {
                    $query->where('from_user_id', $partnerId)
                        ->where('to_user_id', $userId);
                });
            });
        }
        
        // 是否已读筛选
        if (isset($params['is_read']) && $params['is_read'] !== '') {
            $query->where('is_read', $params['is_read']);
        }
        
        // 获取总数
        $total = $query->count();
        
        // 获取分页数据
        $list = $query->order('id', 'desc')
            ->page($page, $limit)
            ->select()
            ->toArray();
        
        // 获取未读数量
        $unreadCount = PrivateMessageEntity::where('to_user_id', $userId)
            ->where('is_read', 0)
            ->count();
        
        return [
            'list' => $list,
            'total' => $total,
            'unread_count' => $unreadCount,
            'page' => $page,
            'limit' => $limit,
        ];
    }
    
    /**
     * 获取用户的对话列表
     *
     * @param int $userId 用户ID
     * @param int $page 页码
     * @param int $limit 每页数量
     * @return array
     */
    public function getConversationList(int $userId, int $page = 1, int $limit = 10)
    {
        // 获取与用户相关的所有对话
        $rawSql = "SELECT 
                CASE 
                    WHEN from_user_id = {$userId} THEN to_user_id 
                    ELSE from_user_id 
                END AS partner_id,
                MAX(id) AS last_message_id
            FROM cy_message_privates
            WHERE (from_user_id = {$userId} OR to_user_id = {$userId})
            AND delete_time IS NULL
            GROUP BY partner_id
            ORDER BY last_message_id DESC
            LIMIT " . (($page - 1) * $limit) . ", {$limit}";
        
        $conversations = Db::query($rawSql);
        
        // 获取总数
        $totalSql = "SELECT COUNT(DISTINCT CASE WHEN from_user_id = {$userId} THEN to_user_id ELSE from_user_id END) AS total
            FROM cy_message_privates
            WHERE (from_user_id = {$userId} OR to_user_id = {$userId})
            AND delete_time IS NULL";
        
        $totalResult = Db::query($totalSql);
        $total = $totalResult[0]['total'] ?? 0;
        
        // 获取每个对话的最后一条消息
        $result = [];
        foreach ($conversations as $conversation) {
            $partnerId = $conversation['partner_id'];
            $lastMessageId = $conversation['last_message_id'];
            
            // 获取最后一条消息
            $lastMessage = PrivateMessageEntity::find($lastMessageId);
            if (!$lastMessage) {
                continue;
            }
            
            // 获取未读消息数量
            $unreadCount = PrivateMessageEntity::where('from_user_id', $partnerId)
                ->where('to_user_id', $userId)
                ->where('is_read', 0)
                ->count();
            
            // 获取对话用户信息
            $partnerInfo = null;
            if ($partnerId > 0) {
                $partnerInfo = Db::name('user')
                    ->field('id, nickname, avatar')
                    ->where('id', $partnerId)
                    ->find();
            } else {
                $partnerInfo = [
                    'id' => 0,
                    'nickname' => '系统',
                    'avatar' => '/static/images/system-avatar.png',
                ];
            }
            
            $result[] = [
                'partner_id' => $partnerId,
                'partner_info' => $partnerInfo,
                'last_message' => $lastMessage->toArray(),
                'unread_count' => $unreadCount,
            ];
        }
        
        return [
            'list' => $result,
            'total' => $total,
            'page' => $page,
            'limit' => $limit,
        ];
    }
    
    /**
     * 获取两个用户之间的对话消息
     *
     * @param int $userId 当前用户ID
     * @param int $partnerId 对话用户ID
     * @param int $page 页码
     * @param int $limit 每页数量
     * @return array
     */
    public function getConversationMessages(int $userId, int $partnerId, int $page = 1, int $limit = 20)
    {
        $query = PrivateMessageEntity::where(function ($query) use ($userId, $partnerId) {
            $query->where(function ($query) use ($userId, $partnerId) {
                $query->where('from_user_id', $userId)
                    ->where('to_user_id', $partnerId);
            })->whereOr(function ($query) use ($userId, $partnerId) {
                $query->where('from_user_id', $partnerId)
                    ->where('to_user_id', $userId);
            });
        });
        
        // 获取总数
        $total = $query->count();
        
        // 获取分页数据
        $list = $query->order('id', 'desc')
            ->page($page, $limit)
            ->select()
            ->toArray();
        
        // 自动标记接收的消息为已读
        PrivateMessageEntity::where('from_user_id', $partnerId)
            ->where('to_user_id', $userId)
            ->where('is_read', 0)
            ->update([
                'is_read' => 1,
                'read_time' => time(),
            ]);
        
        return [
            'list' => $list,
            'total' => $total,
            'page' => $page,
            'limit' => $limit,
        ];
    }
    
    /**
     * 获取单个私信详情
     *
     * @param int $id 私信ID
     * @return array|null
     */
    public function getDetail(int $id)
    {
        return PrivateMessageEntity::find($id);
    }
    
    /**
     * 发送私信
     *
     * @param int $fromUserId 发送者用户ID，0表示系统
     * @param int $toUserId 接收者用户ID
     * @param string $content 私信内容
     * @return int|bool
     */
    public function send(int $fromUserId, int $toUserId, string $content)
    {
        if ($toUserId <= 0) {
            return false;
        }
        
        // 检查接收者的消息设置
        $setting = MessageSettingEntity::where('user_id', $toUserId)->find();
        if ($setting && !$setting->isNotifyEnabled(5)) {
            // 用户已关闭私信
            return false;
        }
        
        $entity = new PrivateMessageEntity();
        $entity->from_user_id = $fromUserId;
        $entity->to_user_id = $toUserId;
        $entity->content = $content;
        $entity->is_read = 0;
        $entity->read_time = 0;
        $entity->save();
        
        return $entity->id;
    }
    
    /**
     * 发送系统私信
     *
     * @param int $toUserId 接收者用户ID
     * @param string $content 私信内容
     * @return int|bool
     */
    public function sendSystemMessage(int $toUserId, string $content)
    {
        return $this->send(0, $toUserId, $content);
    }
    
    /**
     * 标记私信为已读
     *
     * @param int $id 私信ID
     * @param int $userId 用户ID，用于验证权限
     * @return bool
     */
    public function markAsRead(int $id, int $userId)
    {
        $entity = PrivateMessageEntity::find($id);
        if (!$entity || $entity->to_user_id != $userId) {
            return false;
        }
        
        return $entity->markAsRead()->save();
    }
    
    /**
     * 批量标记私信为已读
     *
     * @param array $ids 私信ID数组
     * @param int $userId 用户ID，用于验证权限
     * @return bool
     */
    public function batchMarkAsRead(array $ids, int $userId)
    {
        if (empty($ids) || $userId <= 0) {
            return false;
        }
        
        return PrivateMessageEntity::where('id', 'in', $ids)
            ->where('to_user_id', $userId)
            ->where('is_read', 0)
            ->update([
                'is_read' => 1,
                'read_time' => time(),
            ]);
    }
    
    /**
     * 标记与指定用户的所有私信为已读
     *
     * @param int $userId 当前用户ID
     * @param int $partnerId 对话用户ID
     * @return bool
     */
    public function markAllAsRead(int $userId, int $partnerId)
    {
        if ($userId <= 0) {
            return false;
        }
        
        return PrivateMessageEntity::where('from_user_id', $partnerId)
            ->where('to_user_id', $userId)
            ->where('is_read', 0)
            ->update([
                'is_read' => 1,
                'read_time' => time(),
            ]);
    }
    
    /**
     * 删除私信
     *
     * @param int $id 私信ID
     * @param int $userId 用户ID，用于验证权限
     * @return bool
     */
    public function delete(int $id, int $userId)
    {
        $entity = PrivateMessageEntity::find($id);
        if (!$entity || ($entity->from_user_id != $userId && $entity->to_user_id != $userId)) {
            return false;
        }
        
        return $entity->delete();
    }
    
    /**
     * 批量删除私信
     *
     * @param array $ids 私信ID数组
     * @param int $userId 用户ID，用于验证权限
     * @return bool
     */
    public function batchDelete(array $ids, int $userId)
    {
        if (empty($ids) || $userId <= 0) {
            return false;
        }
        
        return PrivateMessageEntity::where('id', 'in', $ids)
            ->where(function ($query) use ($userId) {
                $query->where('from_user_id', $userId)
                    ->whereOr('to_user_id', $userId);
            })
            ->delete();
    }
    
    /**
     * 删除与指定用户的所有对话
     *
     * @param int $userId 当前用户ID
     * @param int $partnerId 对话用户ID
     * @return bool
     */
    public function deleteConversation(int $userId, int $partnerId)
    {
        if ($userId <= 0 || $partnerId < 0) {
            return false;
        }
        
        return PrivateMessageEntity::where(function ($query) use ($userId, $partnerId) {
            $query->where(function ($query) use ($userId, $partnerId) {
                $query->where('from_user_id', $userId)
                    ->where('to_user_id', $partnerId);
            })->whereOr(function ($query) use ($userId, $partnerId) {
                $query->where('from_user_id', $partnerId)
                    ->where('to_user_id', $userId);
            });
        })->delete();
    }
    
    /**
     * 获取用户未读私信数量
     *
     * @param int $userId 用户ID
     * @return int
     */
    public function getUnreadCount(int $userId)
    {
        if ($userId <= 0) {
            return 0;
        }
        
        return PrivateMessageEntity::where('to_user_id', $userId)
            ->where('is_read', 0)
            ->count();
    }
}
